home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-05
/
pcrte224.zip
/
SOURCE.ZIP
/
SLIP.INC
< prev
next >
Wrap
Text File
|
1992-06-09
|
10KB
|
287 lines
;;******************************************************************************
;; slip.inc slip.inc
;;******************************************************************************
;;
;; Copyright (C) 1989 Vance Morrison
;;
;;
;; Permission to view, compile, and modify for LOCAL (intra-organization)
;; USE ONLY is hereby granted, provided that this copyright and permission
;; notice appear on all copies. Any other use by permission only.
;;
;; Vance Morrison makes no representations about the suitability
;; of this software for any purpose. It is provided "as is" without expressed
;; or implied warranty. See the copywrite notice file for complete details.
;;
;;******************************************************************************
;; slip.inc contains the interface driver for a SLIP interface. This
;; software is responcible for packetizing/depacketizing the data for the
;; serial line and providing data transparency (byte stuffing)
;;
;; The functions provided by this file are
;;
;; SLIP_DECLARE name, i8250, rbuff, rqueue, wbuff, wqueue
;; SLIP_DEFINE name
;; SLIP_CONSUME_in_AL_const_BX_BP_ES name
;; SLIP_WRITE_EMPTY_const_BX_BP_ES name
;; SLIP_WRITE_const_BX_BP_ES name
;;
;; This code assumes that an i8250 interface (WRITE and CAN_WRITE)
;; is available via the 'i8250' variable passed to SLIP_DECLARE
;;
;; slip_&name&_declared ;; one if this interface exists
;; if_&name&_mtu ;; the maximum transmition unit
;; if_&name&_address ;; physical address (dummy value)
;;
;;******************************************************************************
;;******************************************************************************
;; data storage needed by this module
slip_data STRUC
slip_rptr DW 0
slip_rstart DW 0
slip_rend DW 0
slip_resc DB 0
slip_rsyncing DB 0
slip_wptr DW 1 ; bigger than wend means start a new packet
slip_wend DW 0
slip_drops DW 0 ; number of dropped packets
slip_bytes_in DW 0 ; total number of bytes that have come in
slip_bytes_out DW 0 ; total number of bytes that have went out
slip_wesc DB 0
slip_w_idle DB 1 ;; flag set when 8250 write buff idle
slip_data ENDS
SLIP_ESC = 0DBH
SLIP_END = 0C0H
SLIP_ESC_ESC = 0DDH
SLIP_ESC_END = 0DCH
;;******************************************************************************
;; SLIP_DECLARE
SLIP_DECLARE MACRO name, i8250, rbuff, rqueue, wbuff, wqueue
.errb <name>
.errb <wqueue>
.DATA
slip_&name&_declared = 1
slip_&name&_i8250 = i8250
slip_&name&_rbuff = rbuff
slip_&name&_rqueue = rqueue
slip_&name&_wbuff = wbuff
slip_&name&_wqueue = wqueue
if_&name&_mtu = 1006
global slip_&name&_data:slip_data
global if_&name&_address:byte
.CODE
ENDM
;;******************************************************************************
;; SLIP_DEFINE name
;; sets asside memory the named object and initializes it. This
;; routine is a no-op if 'name' was not declared. It jumps to 'fail'
;; if there was an error in setup.
;;
SLIP_DEFINE MACRO name
ifdef slip_&name&_declared
.DATA
slip_&name&_data slip_data <> ;; create storage needed
if_&name&_address DB 6 DUP (0)
.CODE
mov slip_&name&_data.slip_w_idle, 1
endif
ENDM
;;******************************************************************************
;; SLIP_WRITE_EMPTY_const_BX_BP_ES is called at interupt level whenever a
;; character can be written.
SLIP_WRITE_EMPTY_const_BX_BP_ES MACRO name
local done, write_char, no_char
write_char:
SLIP_GETQUEUE_out_AL_const_BX_BP_ES name, no_char
inc slip_&name&_data.slip_bytes_out
I8250_WRITE_in_AL_const_BX_BP_ES %slip_&name&_i8250
I8250_CAN_WRITE_const_BX_CX_BP_SI_DI_ES %slip_&name&_i8250, done
jmp write_char
no_char:
mov slip_&name&_data.slip_w_idle, 1
done:
ENDM
;;******************************************************************************
;; SLIP_WRITE is called whenever a high level write is
;; performed (something is placed in the queue). The call to this routine
;; acts as a 'trigger' that starts the writing if it is not already in
;; progress.
SLIP_WRITE_const_BX_BP_ES MACRO name
local done, write_char, no_char, cant_write
cmp slip_&name&_data.slip_w_idle, 0 ;; are we idle
jz done
write_char:
SLIP_GETQUEUE_out_AL_const_BX_BP_ES name, done
inc slip_&name&_data.slip_bytes_out
I8250_WRITE_in_AL_const_BX_BP_ES %slip_&name&_i8250
I8250_CAN_WRITE_const_BX_CX_BP_SI_DI_ES %slip_&name&_i8250, cant_write
jmp write_char
cant_write:
mov slip_&name&_data.slip_w_idle, 0
done:
ENDM
;;******************************************************************************
;; SLIP_CONSUME is called from the interupt routine whenever a new character
;; is available from this interface. The character is in AL. SLIP_CONSUME's
;; job is to place it in the packet queue.
SLIP_CONSUME_in_AL_const_BX_BP_ES MACRO name
inc slip_&name&_data.slip_bytes_in
SLIP_PUTQUEUE_in_AL_const_const_BX_BP_ES name ; easy is't it?
ENDM
;;******************************************************************************
;; puts a chacacter read in for interface 'name' into the read queue
SLIP_PUTQUEUE_in_AL_const_const_BX_BP_ES MACRO name
local cont_packet, done, not_escaped, try_esc_esc, got_end, got_esc
local drop, not_end, nobuff
mov SI, slip_&name&_data.slip_rptr
or SI, SI ;; rptr = 0 if 'between' packets
jnz cont_packet
cmp AL, SLIP_END
jnz not_end
mov slip_&name&_data.slip_rsyncing, 0
jmp done
not_end:
cmp slip_&name&_data.slip_rsyncing, 0
jnz done
mov CX, if_&name&_mtu
mov DX, AX
BUFF_CHECK_in_CX_out_SI_DI_const_BX_CX_DX_BP_ES %slip_&name&_rbuff,nobuff
mov AX, DX
mov slip_&name&_data.slip_rptr, SI
mov slip_&name&_data.slip_rstart, SI
mov slip_&name&_data.slip_rend, DI
BUFF_GET_in_DI_const_AX_BX_CX_DX_BP_SI_DI_ES %slip_&name&_rbuff
cont_packet:
cmp AL, SLIP_END
jz got_end
cmp AL, SLIP_ESC
jz got_esc
;; what to do if you have a regular character
cmp slip_&name&_data.slip_resc, 0
jz not_escaped
mov slip_&name&_data.slip_resc, 0
cmp AL, SLIP_ESC_END
jnz try_esc_esc
mov AL, SLIP_END
jmp not_escaped
try_esc_esc:
cmp AL, SLIP_ESC_ESC
jnz drop
mov AL, SLIP_ESC
not_escaped:
mov CX, slip_&name&_data.slip_rstart
add CX, if_&name&_mtu
cmp SI, CX
jae drop
mov [SI], AL
inc SI
mov slip_&name&_data.slip_rptr, SI
jmp done
drop:
mov DI,slip_&name&_data.slip_rend
BUFF_FREE_in_DI_const_AX_BX_CX_DX_BP_SI_DI_ES %slip_&name&_rbuff
nobuff:
mov slip_&name&_data.slip_rptr, 0
mov slip_&name&_data.slip_resc, 0
mov slip_&name&_data.slip_rsyncing, 1
inc slip_&name&_data.slip_drops
jmp done
got_esc:
mov slip_&name&_data.slip_resc, 1
jmp done
got_end:
mov CX, SI
mov AX, slip_&name&_data.slip_rstart
sub CX, AX
mov SI, AX
QUEUE_ENQUEUE_out_DI_const_BX_CX_DX_BP_SI_ES %slip_&name&_rqueue, drop
mov [DI+0], SI ;; offset for start ptr
mov DX, slip_&name&_data.slip_rend
mov [DI+2], DX ;; offset for end ptr
mov [DI+4], CX ;; offset for data len (may be less)
mov slip_&name&_data.slip_rptr, 0
done:
ENDM
;;******************************************************************************
;;
SLIP_GETQUEUE_out_AL_const_BX_BP_ES MACRO name, no_char
local cont_packet, end_packet, done, normal_char, check_esc, update_ptr
mov SI, slip_&name&_data.slip_wptr
cmp SI, slip_&name&_data.slip_wend
jb cont_packet
jz end_packet
QUEUE_HEAD_out_SI_const_AX_BX_CX_DX_BP_DI_ES %slip_&name&_wqueue, no_char
mov DI, SI
mov SI, [DI+0] ;; get start ptr
mov slip_&name&_data.slip_wptr, SI
mov AX, [DI+4] ;; get data len
add AX, SI
mov slip_&name&_data.slip_wend, AX
mov AL, SLIP_END
jmp done
end_packet:
mov AL, SLIP_END
inc SI
mov slip_&name&_data.slip_wptr, SI
QUEUE_HEAD_out_SI_const_AX_BX_CX_DX_BP_DI_ES %slip_&name&_wqueue, done
mov DI, [SI+2] ;; get end ptr
BUFF_FREE_in_DI_const_AX_BX_CX_DX_BP_SI_DI_ES %slip_&name&_wbuff
QUEUE_DEQUEUE_in_SI_const_AX_BX_CX_DX_BP_DI_ES %slip_&name&_wqueue
jmp done
cont_packet:
cmp slip_&name&_data.slip_wesc, 0
jz normal_char
mov AL, slip_&name&_data.slip_wesc
mov slip_&name&_data.slip_wesc, 0
jmp update_ptr
normal_char:
mov AL, [SI]
cmp AL, SLIP_END
jnz check_esc
mov slip_&name&_data.slip_wesc, SLIP_ESC_END
mov AL, SLIP_ESC
jmp done
check_esc:
cmp AL, SLIP_ESC
jnz update_ptr
mov slip_&name&_data.slip_wesc, SLIP_ESC_ESC
mov AL, SLIP_ESC
jmp done
update_ptr:
inc SI
mov slip_&name&_data.slip_wptr, SI
done:
ENDM